package com.cch.demo.bus.Aspect;

import cn.hutool.core.bean.BeanUtil;
import com.cch.demo.bus.domain.Customer;
import com.cch.demo.bus.domain.Goods;
import com.cch.demo.bus.domain.Provider;
import com.cch.demo.bus.vo.CustomerVo;
import com.cch.demo.bus.vo.GoodsVo;
import com.cch.demo.bus.vo.ProviderVo;
import com.cch.demo.sys.Aspect.CachePool;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
public class BusinessCacheAspect {

    private Log log = LogFactory.getLog(BusinessCacheAspect.class);

    //声明一个缓存容器
    //从CachePool中获取缓存容器
    private Map<String,Object> CACHE_CONTAINER= CachePool.CACHE_CONTAINER;

    //客户缓存
    private static final String POINTCUT_CUSTOMER_GET = "execution(* com.cch.demo.bus.service.impl.CustomerServiceImpl.getById(..))";
    private static final String POINTCUT_CUSTOMER_INSERT = "execution(* com.cch.demo.bus.service.impl.CustomerServiceImpl.save(..))";
    private static final String POINTCUT_CUSTOMER_UPDETE = "execution(* com.cch.demo.bus.service.impl.CustomerServiceImpl.updateById(..))";
    private static final String POINTCUT_CUSTOMER_DELETE = "execution(* com.cch.demo.bus.service.impl.CustomerServiceImpl.removeById(..))";
    private static final String POINTCUT_CUSTOMER_BATCHDELETE = "execution(* com.cch.demo.bus.service.impl.CustomerServiceImpl.removeByIds(..))";

    private static final String CACHE_CUSTOMER_PROFIX="customer:";

    /**
     * 插入缓存
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINTCUT_CUSTOMER_INSERT)
    public Boolean cacheCustomerInsert(ProceedingJoinPoint joinPoint) throws Throwable {
        Customer customer = (Customer)joinPoint.getArgs()[0];
        Boolean isSuccess = (Boolean)joinPoint.proceed();
        if(isSuccess){
            log.info("---向缓存中插入"+CACHE_CUSTOMER_PROFIX+customer.getId());
            CACHE_CONTAINER.put(CACHE_CUSTOMER_PROFIX+customer.getId(),customer);
            return isSuccess;
        }else{
            return isSuccess;
        }
    }
    /**
     * 查询缓存
     * @param jionPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINTCUT_CUSTOMER_GET)
    public Customer cacheCustomerGet(ProceedingJoinPoint jionPoint) throws Throwable {

        Integer id = (Integer)jionPoint.getArgs()[0];
        Customer customer = (Customer)CACHE_CONTAINER.get(CACHE_CUSTOMER_PROFIX+id);
        if(customer!=null){
            log.info("---缓存中存在"+CACHE_CUSTOMER_PROFIX+id);
            return customer;
        }else{
            log.info("---缓存中不存在"+CACHE_CUSTOMER_PROFIX+id);
            customer = (Customer)jionPoint.proceed();
            CACHE_CONTAINER.put(CACHE_CUSTOMER_PROFIX+id,customer);
            return customer;
        }
    }

    /**
     * 修改缓存
     * @param jionPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINTCUT_CUSTOMER_UPDETE)
    public Boolean cacheCustomerUpdate(ProceedingJoinPoint jionPoint) throws Throwable {
        Customer customer1 = (Customer)jionPoint.getArgs()[0];
        Boolean isSuccess  = (Boolean) jionPoint.proceed();
        if (isSuccess){
            //从缓存中获取Customer
            Customer customer = (Customer) CACHE_CONTAINER.get(CACHE_CUSTOMER_PROFIX+customer1.getId());
            //如果缓存中存在该customer
            if(customer!=null){
                log.info("----缓存中存在未修改的"+CACHE_CUSTOMER_PROFIX+customer1.getId()+"进行删除重新加载");
                //移除原先的customer
                CACHE_CONTAINER.remove(CACHE_CUSTOMER_PROFIX+customer1.getId());
                //插入修改后的customer
                Customer customer2 = new Customer();
                BeanUtil.copyProperties(customer1,customer2);
                CACHE_CONTAINER.put(CACHE_CUSTOMER_PROFIX+customer1.getId(),customer2);
                //缓存中不存在该Customer
            }else{
                log.info("-----缓存中不存在未修改的"+CACHE_CUSTOMER_PROFIX+customer1.getId());
                Customer customer2 = new Customer();
                BeanUtil.copyProperties(customer1,customer2);
                CACHE_CONTAINER.put(CACHE_CUSTOMER_PROFIX+customer1.getId(),customer2);
            }
        }
        return isSuccess;
    }

    @Around(value = POINTCUT_CUSTOMER_DELETE)
    public Boolean cacheCustomerDetele(ProceedingJoinPoint jionPoint) throws Throwable {
        Integer id = (Integer) jionPoint.getArgs()[0];
        Boolean isSuccess  = (Boolean) jionPoint.proceed();
        if(isSuccess){
            Customer customer = (Customer)CACHE_CONTAINER.get(CACHE_CUSTOMER_PROFIX+id);
            if(customer!=null){
                log.info("删除缓存中的Customer");
                CACHE_CONTAINER.remove(CACHE_CUSTOMER_PROFIX+id);
            }
        }
        return isSuccess;
    }

    /**
     * 批量删除
     * @param jionPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINTCUT_CUSTOMER_BATCHDELETE)
    public Boolean cacheCustomerBatchDetele(ProceedingJoinPoint jionPoint) throws Throwable {
        Collection<Serializable> ids = ( Collection<Serializable>) jionPoint.getArgs()[0];
        Boolean isSuccess  = (Boolean) jionPoint.proceed();
        if(isSuccess){
            for(Serializable id:ids) {
                Customer customer = (Customer) CACHE_CONTAINER.get(CACHE_CUSTOMER_PROFIX + id);
                if (customer != null) {
                    log.info("删除缓存中的Customer"+CACHE_CUSTOMER_PROFIX + id);
                    CACHE_CONTAINER.remove(CACHE_CUSTOMER_PROFIX + id);
                }
            }
        }
        return isSuccess;
    }

    private static final String POINTCUT_PROVIDER_GET = "execution(* com.cch.demo.bus.service.impl.ProviderServiceImpl.getById(..))";
    private static final String POINTCUT_PROVIDER_INSERT = "execution(* com.cch.demo.bus.service.impl.ProviderServiceImpl.save(..))";
    private static final String POINTCUT_PROVIDER_UPDETE = "execution(* com.cch.demo.bus.service.impl.ProviderServiceImpl.updateById(..))";
    private static final String POINTCUT_PROVIDER_DELETE = "execution(* com.cch.demo.bus.service.impl.ProviderServiceImpl.removeById(..))";
    private static final String POINTCUT_PROVIDER_BATCHDELETE = "execution(* com.cch.demo.bus.service.impl.ProviderServiceImpl.removeByIds(..))";

    //供应商缓存
    private static final String CACHE_PROVIDER_PROFIX="provider:";

    /**
     * 插入缓存
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINTCUT_PROVIDER_INSERT)
    public Boolean cacheProviderInsert(ProceedingJoinPoint joinPoint) throws Throwable {
        Provider provider = (Provider)joinPoint.getArgs()[0];
        Boolean isSuccess = (Boolean)joinPoint.proceed();
        if(isSuccess){
            log.info("---向缓存中插入"+CACHE_PROVIDER_PROFIX+provider.getId());
            CACHE_CONTAINER.put(CACHE_PROVIDER_PROFIX+provider.getId(),provider);
            return isSuccess;
        }else{
            return isSuccess;
        }
    }
    /**
     * 查询缓存
     * @param jionPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINTCUT_PROVIDER_GET)
    public Provider cacheProviderGet(ProceedingJoinPoint jionPoint) throws Throwable {

        Integer id = (Integer)jionPoint.getArgs()[0];
        Provider provider = (Provider)CACHE_CONTAINER.get(CACHE_PROVIDER_PROFIX+id);
        if(provider!=null){
            log.info("---缓存中存在"+CACHE_PROVIDER_PROFIX+id);
            return provider;
        }else{
            log.info("---缓存中不存在"+CACHE_PROVIDER_PROFIX+id);
            provider = (Provider)jionPoint.proceed();
            CACHE_CONTAINER.put(CACHE_PROVIDER_PROFIX+id,provider);
            return provider;
        }
    }

    /**
     * 修改缓存
     * @param jionPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINTCUT_PROVIDER_UPDETE)
    public Boolean cacheProviderUpdate(ProceedingJoinPoint jionPoint) throws Throwable {
        Provider provider1 = (Provider)jionPoint.getArgs()[0];
        Boolean isSuccess  = (Boolean) jionPoint.proceed();
        if (isSuccess){
            //从缓存中获取Provider
            Provider provider = (Provider) CACHE_CONTAINER.get(CACHE_PROVIDER_PROFIX+provider1.getId());
            //如果缓存中存在该provider
            if(provider!=null){
                log.info("----缓存中存在未修改的"+CACHE_PROVIDER_PROFIX+provider1.getId()+"进行删除重新加载");
                //移除原先的provider
                CACHE_CONTAINER.remove(CACHE_PROVIDER_PROFIX+provider1.getId());
                //插入修改后的provider
                Provider provider2 = new Provider();
                BeanUtil.copyProperties(provider1,provider2);
                CACHE_CONTAINER.put(CACHE_PROVIDER_PROFIX+provider1.getId(),provider2);
                //缓存中不存在该Provider
            }else{
                log.info("-----缓存中不存在未修改的"+CACHE_PROVIDER_PROFIX+provider1.getId());
                Provider provider2 = new Provider();
                BeanUtil.copyProperties(provider1,provider2);
                CACHE_CONTAINER.put(CACHE_PROVIDER_PROFIX+provider1.getId(),provider2);
            }
        }
        return isSuccess;
    }

    @Around(value = POINTCUT_PROVIDER_DELETE)
    public Boolean cacheProviderDetele(ProceedingJoinPoint jionPoint) throws Throwable {
        Integer id = (Integer) jionPoint.getArgs()[0];
        Boolean isSuccess  = (Boolean) jionPoint.proceed();
        if(isSuccess){
            Provider provider = (Provider)CACHE_CONTAINER.get(CACHE_PROVIDER_PROFIX+id);
            if(provider!=null){
                log.info("删除缓存中的Provider");
                CACHE_CONTAINER.remove(CACHE_PROVIDER_PROFIX+id);
            }
        }
        return isSuccess;
    }

    /**
     * 批量删除
     * @param jionPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINTCUT_PROVIDER_BATCHDELETE)
    public Boolean cacheProviderBatchDetele(ProceedingJoinPoint jionPoint) throws Throwable {
        Collection<Serializable> ids = ( Collection<Serializable>) jionPoint.getArgs()[0];
        Boolean isSuccess  = (Boolean) jionPoint.proceed();
        if(isSuccess){
            for(Serializable id:ids) {
                Provider provider = (Provider) CACHE_CONTAINER.get(CACHE_PROVIDER_PROFIX + id);
                if (provider != null) {
                    log.info("删除缓存中的Provider"+CACHE_PROVIDER_PROFIX + id);
                    CACHE_CONTAINER.remove(CACHE_PROVIDER_PROFIX + id);
                }
            }
        }
        return isSuccess;
    }

    //商品数据的缓存 声明切面表达式
    private static final String POINTCUT_GOODS_GET = "execution(* com.cch.demo.bus.service.impl.GoodsServiceImpl.getById(..))";
    private static final String POINTCUT_GOODS_INSERT = "execution(* com.cch.demo.bus.service.impl.GoodsServiceImpl.save(..))";
    private static final String POINTCUT_GOODS_UPDETE = "execution(* com.cch.demo.bus.service.impl.GoodsServiceImpl.updateById(..))";
    private static final String POINTCUT_GOODS_DELETE = "execution(* com.cch.demo.bus.service.impl.GoodsServiceImpl.removeById(..))";
    private static final String POINTCUT_GOODS_BATCHDELETE = "execution(* com.cch.demo.bus.service.impl.GoodsServiceImpl.removeByIds(..))";

    //供应商缓存
    private static final String CACHE_GOODS_PROFIX="goods:";

    /**
     * 插入缓存
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINTCUT_GOODS_INSERT)
    public Boolean cacheGoodsInsert(ProceedingJoinPoint joinPoint) throws Throwable {
        Goods goods = (Goods)joinPoint.getArgs()[0];
        Boolean isSuccess = (Boolean)joinPoint.proceed();
        if(isSuccess){
            log.info("---向缓存中插入"+CACHE_GOODS_PROFIX+goods.getId());
            CACHE_CONTAINER.put(CACHE_GOODS_PROFIX+goods.getId(),goods);
            return isSuccess;
        }else{
            return isSuccess;
        }
    }
    /**
     * 查询缓存
     * @param jionPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINTCUT_GOODS_GET)
    public Goods cacheGoodsGet(ProceedingJoinPoint jionPoint) throws Throwable {

        Integer id = (Integer)jionPoint.getArgs()[0];
        Goods goods = (Goods)CACHE_CONTAINER.get(CACHE_GOODS_PROFIX+id);
        if(goods!=null){
            log.info("---缓存中存在"+CACHE_GOODS_PROFIX+id);
            return goods;
        }else{
            log.info("---缓存中不存在"+CACHE_GOODS_PROFIX+id);
            goods = (Goods)jionPoint.proceed();
            CACHE_CONTAINER.put(CACHE_GOODS_PROFIX+id,goods);
            return goods;
        }
    }

    /**
     * 修改缓存
     * @param jionPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINTCUT_GOODS_UPDETE)
    public Boolean cacheGoodsUpdate(ProceedingJoinPoint jionPoint) throws Throwable {
        Goods goods1 = (Goods)jionPoint.getArgs()[0];
        Boolean isSuccess  = (Boolean) jionPoint.proceed();
        if (isSuccess){
            //从缓存中获取Goods
            Goods goods = (Goods) CACHE_CONTAINER.get(CACHE_GOODS_PROFIX+goods1.getId());
            //如果缓存中存在该goods
            if(goods!=null){
                log.info("----缓存中存在未修改的"+CACHE_GOODS_PROFIX+goods1.getId()+"进行删除重新加载");
                //移除原先的goods
                CACHE_CONTAINER.remove(CACHE_GOODS_PROFIX+goods1.getId());
                //插入修改后的goods
                Goods goods2 = new Goods();
                BeanUtil.copyProperties(goods1,goods2);
                CACHE_CONTAINER.put(CACHE_GOODS_PROFIX+goods1.getId(),goods2);
                //缓存中不存在该Goods
            }else{
                log.info("-----缓存中不存在未修改的"+CACHE_GOODS_PROFIX+goods1.getId());
                Goods goods2 = new Goods();
                BeanUtil.copyProperties(goods1,goods2);
                CACHE_CONTAINER.put(CACHE_GOODS_PROFIX+goods1.getId(),goods2);
            }
        }
        return isSuccess;
    }

    @Around(value = POINTCUT_GOODS_DELETE)
    public Boolean cacheGoodsDetele(ProceedingJoinPoint jionPoint) throws Throwable {
        Integer id = (Integer) jionPoint.getArgs()[0];
        Boolean isSuccess  = (Boolean) jionPoint.proceed();
        if(isSuccess){
            Goods goods = (Goods)CACHE_CONTAINER.get(CACHE_GOODS_PROFIX+id);
            if(goods!=null){
                log.info("删除缓存中的Goods");
                CACHE_CONTAINER.remove(CACHE_GOODS_PROFIX+id);
            }
        }
        return isSuccess;
    }

    /**
     * 批量删除
     * @param jionPoint
     * @return
     * @throws Throwable
     */
    @Around(value = POINTCUT_GOODS_BATCHDELETE)
    public Boolean cacheGoodsBatchDetele(ProceedingJoinPoint jionPoint) throws Throwable {
        Collection<Serializable> ids = ( Collection<Serializable>) jionPoint.getArgs()[0];
        Boolean isSuccess  = (Boolean) jionPoint.proceed();
        if(isSuccess){
            for(Serializable id:ids) {
                Goods goods = (Goods) CACHE_CONTAINER.get(CACHE_GOODS_PROFIX + id);
                if (goods != null) {
                    log.info("删除缓存中的Goods"+CACHE_GOODS_PROFIX + id);
                    CACHE_CONTAINER.remove(CACHE_GOODS_PROFIX + id);
                }
            }
        }
        return isSuccess;
    }




}
